package cn.study.forkjointest.recursiveaction;

import cn.study.forkjointest.util.Utils;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author     ：跟大佳一起学架构
 * @Description： JDK常用sort的区别
 */
public class JdkListTest {
    public static void main(String[] args){

        int[] arrayToSortByMergeSort1 = Utils.buildRandomIntArray(20_000_000);
        int[] arrayToSortByMergeSort2 = Utils.buildRandomIntArray(20_000_000);
        int[] arrayToSortByMergeSort3 = Utils.buildRandomIntArray(20_000_000);

        long startTime = System.nanoTime();

        //  二、list排序对比
        // list对比
        System.out.println("数组转list开始--------------------------");
        List<Integer> numberList1 = Arrays.stream(arrayToSortByMergeSort1).boxed().collect(Collectors.toList());
        List<Integer> numberList2 = Arrays.stream(arrayToSortByMergeSort2).boxed().collect(Collectors.toList());
        List<Integer> numberList3 = Arrays.stream(arrayToSortByMergeSort3).boxed().collect(Collectors.toList());
        System.out.println("list数据准备好了！！！:"+(System.nanoTime()-startTime)/(1000f*1000f));
        startTime = System.nanoTime();

        // 1、普通排序
        Collections.sort(numberList1);
        System.out.println("归并排序:" + (System.nanoTime()-startTime)/(1000f*1000f));

        startTime = System.nanoTime();
        // 2、lamdba stream 用到了 归并排序
        numberList2.stream().sorted().collect(Collectors.toList());;
        System.out.println("lamdba stream:"+(System.nanoTime()-startTime)/(1000f*1000f));

        startTime = System.nanoTime();
        // 3、lamdba parallelStream 用到了forkJoin 并行归并排序
        numberList3.parallelStream().sorted().collect(Collectors.toList());;
        System.out.println("lamdba parallelStream:"+(System.nanoTime()-startTime)/(1000f*1000f));
    }



    // 主方法调用归并排序
    public static void mergeSort(int[] array) {
        if (array.length < 2) {
            return; // 基本情况，数组只有一个元素或为空时不需要排序
        }
        int mid = array.length / 2;
        int[] left = new int[mid];
        int[] right = new int[array.length - mid];

        // 分割数组到两个子数组
        for (int i = 0; i < mid; i++) {
            left[i] = array[i];
        }
        for (int i = mid; i < array.length; i++) {
            right[i - mid] = array[i];
        }

        // 递归对两个子数组进行归并排序
        mergeSort(left);
        mergeSort(right);

        // 合并排序后的子数组
        merge(array, left, right);
    }

    // 合并两个已排序的子数组
    private static void merge(int[] array, int[] left, int[] right) {
        int i = 0, j = 0, k = 0;
        while (i < left.length && j < right.length) {
            if (left[i] <= right[j]) {
                array[k++] = left[i++];
            } else {
                array[k++] = right[j++];
            }
        }
        // 将剩余元素复制到原数组
        while (i < left.length) {
            array[k++] = left[i++];
        }
        while (j < right.length) {
            array[k++] = right[j++];
        }
    }
}